package com.snake;

import com.common.GameBoard;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;

// 主窗口
@SuppressWarnings("serial")
class MainWindow extends JFrame implements ActionListener, KeyListener, WindowFocusListener, Game.Callback {
    private final JButton mButtonHelp;          // "帮助"按钮
    private final JToggleButton mButtonMusic;   // "播放音乐"按钮
    private final JToggleButton mButtonPause;   // "暂停"按钮
    private final JButton mButtonStart;         // "开始"按钮
    private Game mGame;                         // 游戏
    private final JLabel mLabelDifficulty;      // "难度"标签
    private final JLabel mLabelScore;           // "得分"标签

    /**
     * 构造方法。
     */
    public MainWindow() {
        // 设置当单击右上角的X按钮时退出程序
        super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // 设置窗口标题
        super.setTitle(Const.getString("IDS_APP_NAME"));

        // 设置窗口尺寸不能改变
        super.setResizable(false);

        // 设置窗口尺寸
        super.setSize(Const.WIDTH, Const.HEIGHT);

        // 窗口窗口居中
        super.setLocationRelativeTo(null);

        // 监听键盘事件
        super.addKeyListener(this);

        // 监听窗口焦点事件
        super.addWindowFocusListener(this);

        // 创建工具栏
        final JToolBar toolbar = new JToolBar();
        toolbar.setFloatable(false);
        super.add(toolbar, BorderLayout.NORTH);

        // 设置"开始"按钮
        mButtonStart = new JButton();
        mButtonStart.setIcon(new ImageIcon("res/Start.png"));
        mButtonStart.setToolTipText(Const.getString("IDS_START"));
        mButtonStart.setFocusable(false);
        mButtonStart.setBorderPainted(false);
        mButtonStart.addActionListener(this);
        toolbar.add(mButtonStart);

        // 设置"暂停"按钮
        mButtonPause = new JToggleButton();
        mButtonPause.setEnabled(false);
        mButtonPause.setIcon(new ImageIcon("res/Pause.png"));
        mButtonPause.setToolTipText(Const.getString("IDS_PAUSE"));
        mButtonPause.setFocusable(false);
        mButtonPause.setBorderPainted(false);
        mButtonPause.addActionListener(this);
        toolbar.add(mButtonPause);

        // 设置"播放音乐"按钮
        mButtonMusic = new JToggleButton();
        mButtonMusic.setIcon(new ImageIcon("res/PlayMusic.png"));
        mButtonMusic.setToolTipText(Const.getString("IDS_MUSIC"));
        mButtonMusic.setFocusable(false);
        mButtonMusic.setBorderPainted(false);
        mButtonMusic.addActionListener(this);
        toolbar.add(mButtonMusic);

        // 设置"帮助"按钮
        mButtonHelp = new JButton();
        mButtonHelp.setIcon(new ImageIcon("res/Help.png"));
        mButtonHelp.setToolTipText(Const.getString("IDS_HELP"));
        mButtonHelp.setFocusable(false);
        mButtonHelp.setBorderPainted(false);
        mButtonHelp.addActionListener(this);
        toolbar.add(mButtonHelp);

        // 创建状态栏
        final GridBagLayout layout = new GridBagLayout();
        final JToolBar statusBar = new JToolBar();
        statusBar.setLayout(layout);
        statusBar.setFloatable(false);
        super.add(statusBar, BorderLayout.SOUTH);

        final GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.weightx = 1;

        // 设置"难度"标签
        mLabelDifficulty = new JLabel();
        mLabelDifficulty.setBorder(BorderFactory.createEtchedBorder());
        mLabelDifficulty.setText(Const.getString("IDS_DIFFICULTY"));
        layout.setConstraints(mLabelDifficulty, gbc);
        statusBar.add(mLabelDifficulty);

        // 设置"得分"标签
        mLabelScore = new JLabel();
        mLabelScore.setBorder(BorderFactory.createEtchedBorder());
        mLabelScore.setText(Const.getString("IDS_SCORE"));
        layout.setConstraints(mLabelScore, gbc);
        statusBar.add(mLabelScore);

        // 创建游戏区域
        final GameBoard gameBoard = new GameBoard(this, 0, 0, Const.GAME_BOARD_WIDTH, Const.GAME_BOARD_HEIGHT);

        // 创建游戏
        mGame = new Game(this, gameBoard.getDrawer(), gameBoard);
    }

    /**
     * 所有按钮的单击响应方法。
     * @param e 事件相关信息
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        final Object source = e.getSource();
        if (source == mButtonStart) {
            this.onButtonStartClicked();
        } else if (source == mButtonHelp) {
            this.onButtonHelpClicked();
        } else if (source == mButtonPause) {
            this.onButtonPauseClicked();
        } else if (source == mButtonMusic) {
            this.onButtonMusicClicked();
        }
    }

    /**
     * 按键事件的响应方法。
     * @param e 事件相关信息
     */
    @Override
    public void keyPressed(KeyEvent e) {
        mGame.onKeyPressed(e.getKeyCode());
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    /**
     * "帮助"按钮的单击响应方法。
     */
    private void onButtonHelpClicked() {
        JOptionPane.showMessageDialog(this, Const.getString("IDS_HELP_TEXT"), " ", JOptionPane.INFORMATION_MESSAGE);
    }

    /**
     * "播放音乐"按钮的单击响应方法。
     */
    private void onButtonMusicClicked() {
        final boolean playingMusic = mGame.playMusic();
        mButtonMusic.setSelected(playingMusic);
    }

    /**
     * "暂停"按钮的单击响应方法。
     */
    private void onButtonPauseClicked() {
        mGame.pause();
        mButtonPause.setSelected(mGame.getStatus() == Game.Status.PAUSED);
    }
    
    /**
     * "开始"按钮的单击响应方法。
     */
    private void onButtonStartClicked() {
        // 游戏开始
        mGame.start();

        // 设置按钮状态
        mButtonPause.setEnabled(true);
        mButtonPause.setSelected(false);

        // 设置状态栏上的文字
        mLabelDifficulty.setText(Const.getString("IDS_DIFFICULTY") + 1);
        mLabelScore.setText(Const.getString("IDS_SCORE") + 0);
    }

    /**
     * 难度增加事件的响应方法。
     * @param difficulty    难度
     */
    @Override
    public void onDifficultyUp(int difficulty) {
        final String text = Const.getString("IDS_DIFFICULTY") + difficulty;
        mLabelDifficulty.setText(text);
    }

    /**     
     * 游戏结束事件的响应方法。
     * @param isWon 胜利则为 true，否则为 false
     */
    @Override
    public void onGameOver(boolean isWon) {
        if (isWon) {
            JOptionPane.showMessageDialog(this, Const.getString("IDS_WON"), " ", JOptionPane.INFORMATION_MESSAGE);
        } else {
            JOptionPane.showMessageDialog(this, Const.getString("IDS_LOST"), " ", JOptionPane.INFORMATION_MESSAGE);
        }
        
        mButtonPause.setEnabled(false);
        mButtonPause.setSelected(false);
    }

    /**
     * 得分事件的响应方法。
     * @param score 得分
     */
    @Override
    public void onScore(int score) {
        final String text = Const.getString("IDS_SCORE") + score;
        mLabelScore.setText(text);
    }

    @Override
    public void windowGainedFocus(WindowEvent e) {
    }

    /**
     * 窗口失去焦点事件的响应方法。
     * @param e 事件相关信息
     */
    @Override
    public void windowLostFocus(WindowEvent e) {
        final Game.Status status = mGame.getStatus();
        if (status == Game.Status.PLAYING) {
            this.onButtonPauseClicked();
        }
    }
}
